﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Areaexportimg.Model;
using Areaexportimg.Utils;
using GalaSoft.MvvmLight.Messaging;

namespace Areaexportimg
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();

            Messenger.Default.Register<DrawPathData>(this, "ShowPathData", ShowPathData);
            this.Loaded += MainWindow_Loaded;


        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            wBitmap = new WriteableBitmap(500, 400, 96, 96, PixelFormats.Pbgra32, null);
            DisplayImage.Source = wBitmap;
            // drawTest();
        }

        WriteableBitmap wBitmap;
        private void drawImage(string color, List<List<Point>> points, string imageName)
        {
            wBitmap.Lock();
            var backBitmap = new System.Drawing.Bitmap(500, 400, wBitmap.BackBufferStride, System.Drawing.Imaging.PixelFormat.Format32bppPArgb, wBitmap.BackBuffer);

            var graphics = System.Drawing.Graphics.FromImage(backBitmap);
            graphics.Clear(System.Drawing.Color.Transparent);//整张画布置为白色

            ////画一些随机线
            //Random rand = new Random();
            //for (int i = 0; i < 100; i++)
            //{
            //    int x1 = rand.Next(width);
            //    int x2 = rand.Next(width);
            //    int y1 = rand.Next(height);
            //    int y2 = rand.Next(height);
            //    graphics.DrawLine(System.Drawing.Pens.Red, x1, y1, x2, y2);
            //}

            points.ForEach(list =>
            {
                var drawpoints = new List<System.Drawing.Point>();
                list.ForEach(point =>
                {
                    drawpoints.Add(new System.Drawing.Point(point.X.ToInt32(), point.Y.ToInt32()));
                });

                var brushConverter = new BrushConverter();
                System.Drawing.ColorConverter convert = new System.Drawing.ColorConverter();
                var brush = new System.Drawing.SolidBrush((System.Drawing.Color)convert.ConvertFromString(color));
                var penbrush = new System.Drawing.SolidBrush((System.Drawing.Color)convert.ConvertFromString("#5427C8"));
                var pen = new System.Drawing.Pen(penbrush, 2);
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid; //实线
                graphics.DrawPolygon(pen, drawpoints.ToArray());
                graphics.FillPolygon(brush, drawpoints.ToArray());

            });


            graphics.Flush();
            graphics.Dispose();
            graphics = null;

            backBitmap.Save(imageName + color + ".png");
            backBitmap.Dispose();
            backBitmap = null;

            wBitmap.AddDirtyRect(new Int32Rect(0, 0, 500, 400));
            wBitmap.Unlock();
        }

        private void ShowPathData(DrawPathData drawData)
        {
            // <Path x:Name="currentPath" Fill="Black" StrokeThickness="1" Stroke="Black"></Path>
            Dispatcher.BeginInvoke(new Action(() =>
            {
                //var list = new List<List<Point>>();

                //drawData.PointDatas.ForEach(group =>
                //{
                //    var drawPoints = new List<Point>();

                //    var minX = group.Points.OrderBy(m => m.X).First().X;
                //    var minY = group.Points.OrderBy(m => m.Y).First().Y;


                //    for (var i = 0; i < group.Points.Count; i++)
                //    {
                //        group.Points[i] = new Point(group.Points[i].X + (minX < 0 ? Math.Abs(minX) : 0), group.Points[i].Y + (minY < 0 ? Math.Abs(minY) : 0));
                //    }


                //    minX = group.Points.OrderBy(m => m.X).First().X;
                //    minY = group.Points.OrderBy(m => m.Y).First().Y;
                //    for (var i = 0; i < group.Points.Count; i++)
                //    {
                //        var x = group.Points[i].X - minX;
                //        var y = group.Points[i].Y - minY;
                //        group.Points[i] = new Point(x, y);
                //    }

                //    minX = group.Points.OrderBy(m => m.X).First().X;
                //    minY = group.Points.OrderBy(m => m.Y).First().Y;
                //    var maxX = group.Points.OrderByDescending(m => m.X).First().X;
                //    var maxY = group.Points.OrderByDescending(m => m.Y).First().Y;

                //    var scaley = (maxY - minY) / 400;
                //    var scalex = (maxX - minX) / 500;
                //    var scale = scaley> scalex? scaley : scalex;
                //    for (var i = 0; i < group.Points.Count; i++)
                //    {
                //        var x = group.Points[i].X / scale;
                //        var y = 400 - group.Points[i].Y / scale;
                //        group.Points[i] = new Point(x, y);
                //    }

                //    group.Points.ForEach(m =>
                //    {
                //        drawPoints.Add(new Point(m.X, m.Y));
                //    });

                //    list.Add(drawPoints);

                //});
                var list = ComputePoints(drawData);
                drawImage(drawData.Color.ToString(), list, drawData.Name);

            }));

        }

        private List<List<Point>> ComputePoints(DrawPathData drawData)
        {
            var list = new List<List<Point>>();

            var alldatas = drawData.PointDatas.SelectMany(m => m.Points).ToList();
            if (drawData.LocationPoints != null) 
            {
                alldatas = drawData.LocationPoints;
            }
            var minX = alldatas.OrderBy(m => m.X).First().X;
            var minY = alldatas.OrderBy(m => m.Y).First().Y;

            drawData.PointDatas.ForEach(group =>
            {
                var drawPoints = new List<Point>();

                for (var i = 0; i < group.Points.Count; i++)
                {
                    group.Points[i] = new Point(group.Points[i].X + (minX < 0 ? Math.Abs(minX) : 0), group.Points[i].Y + (minY < 0 ? Math.Abs(minY) : 0));
                }
            });
            //        for (var i = 0; i < alldatas.Count; i++)
            //{
            //    alldatas[i] = new Point(alldatas[i].X + (minX < 0 ? Math.Abs(minX) : 0), alldatas[i].Y + (minY < 0 ? Math.Abs(minY) : 0));
            //}


            minX = alldatas.OrderBy(m => m.X).First().X;
            minY = alldatas.OrderBy(m => m.Y).First().Y;

            drawData.PointDatas.ForEach(group =>
            {
                var drawPoints = new List<Point>();

                for (var i = 0; i < group.Points.Count; i++)
                {
                    var x = group.Points[i].X - minX;
                    var y = group.Points[i].Y - minY;
                    group.Points[i] = new Point(x, y);
                }
            });
            //for (var i = 0; i < alldatas.Count; i++)
            //{
            //    var x = alldatas[i].X - minX;
            //    var y = alldatas[i].Y - minY;
            //    alldatas[i] = new Point(x, y);
            //}

            minX = alldatas.OrderBy(m => m.X).First().X;
            minY = alldatas.OrderBy(m => m.Y).First().Y;
            var maxX = alldatas.OrderByDescending(m => m.X).First().X;
            var maxY = alldatas.OrderByDescending(m => m.Y).First().Y;

            var scaley = (maxY - minY) / 400;
            var scalex = (maxX - minX) / 500;
            var scale = scaley > scalex ? scaley : scalex;

            drawData.PointDatas.ForEach(group =>
            {
                var drawPoints = new List<Point>();

                for (var i = 0; i < group.Points.Count; i++)
                {
                    var x = group.Points[i].X / scale;
                    var y = 400 - group.Points[i].Y / scale;
                    group.Points[i] = new Point(x, y);
                }
            });
            //for (var i = 0; i < alldatas.Count; i++)
            //{
            //    var x = alldatas[i].X / scale;
            //    var y = 400 - alldatas[i].Y / scale;
            //    alldatas[i] = new Point(x, y);
            //}
            drawData.PointDatas.ForEach(group =>
            {
                var drawPoints = new List<Point>();

                group.Points.ForEach(m =>
                {
                    drawPoints.Add(new Point(m.X, m.Y));
                });

                list.Add(drawPoints);
            });
            return list;
        }
    }
}
